package com.google.api.sample;

/*
 * Copyright (c) 2012 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

import com.google.api.client.auth.oauth2.draft10.AccessTokenResponse;
import com.google.api.client.auth.oauth2.draft10.AuthorizationRequestUrl;
import com.google.api.client.googleapis.auth.oauth2.draft10.GoogleAccessTokenRequest;
import com.google.api.client.googleapis.auth.oauth2.draft10.GoogleAuthorizationRequestUrl;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.logging.Logger;

/**
 * A servlet which handles the OAuth 2.0 flow. Once authenticated, the OAuth
 * token is stored in session.authToken.
 *
 * @author Jennifer Murphy
 */
public class OAuth2Servlet extends HttpServlet {
  private static final Logger log = Logger.getLogger(OAuth2Servlet.class.getName());

  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    HttpSession session = req.getSession();

    // Check for an error returned by OAuth
    String error = req.getParameter("error");
    if (error != null) {
      resp.setContentType("text/plain");
      resp.getWriter().println("There was a problem during authentication: " + error);
      log.severe("There was a problem during authentication: " + error);
      return;
    }

    // When we're redirected back from the OAuth 2.0 grant page, a code will be
    // supplied in a GET parameter named 'code'
    String code = req.getParameter("code");
    if (code == null || code.isEmpty()) {
      // Build the authorization URL
      GoogleAuthorizationRequestUrl authorizeUrl = new GoogleAuthorizationRequestUrl(
              ConfigHelper.CLIENT_ID,
              ConfigHelper.REDIRECT_URI,
              ConfigHelper.SCOPES
      );
      authorizeUrl.redirectUri = ConfigHelper.REDIRECT_URI;
      authorizeUrl.scope = ConfigHelper.SCOPES;
      // Setting offline access type and forced approval prompt will guarantee
      // that we always have an OAuth refresh token
      authorizeUrl.setAccessType("offline");
      authorizeUrl.setApprovalPrompt("force");
      String authorizationUrl = authorizeUrl.build();

      log.info("Redirecting browser for OAuth 2.0 authorization to " + authorizationUrl);
      resp.sendRedirect(authorizationUrl);
    } else {
      log.info("Exchanging OAuth code for access token using server side call");

      AccessTokenResponse accessTokenResponse = new GoogleAccessTokenRequest.GoogleAuthorizationCodeGrant(
              new NetHttpTransport(),
              new GsonFactory(),
              ConfigHelper.CLIENT_ID,
              ConfigHelper.CLIENT_SECRET,
              code,
              ConfigHelper.REDIRECT_URI
      ).execute();

      log.info("Storing authentication token into the session");
      session.setAttribute("accessToken", accessTokenResponse.accessToken);
      session.setAttribute("refreshToken", accessTokenResponse.refreshToken);

      //The authentication is all done! Redirect back to the samples index so you can play with them.
      resp.sendRedirect("/");
    }
  }
}
